﻿using System;
using FireStarter.Base;
using FireStarter.Base.BusinessObjectMerger;
using Firestarter.DB.Schema.BO;

namespace Firestarter.DB.Schema.Logic
{
    public class DBMergeDBForeignKeyColumn : DBMergeBO<DBForeignKeyColumn>
    {

        protected override void CopyRelationships(DBForeignKeyColumn fromFKColumn, DBForeignKeyColumn toFKColumn)
        {
            //We only have to deal with the case of merging a DBPrimaryKeys Column relationship.
            // The merging of this relationship is not standard since we need to find the 
            // column from the toTable and and linke this PrimaryKeyColumn to it.
            if (fromFKColumn == null) return;

            if (fromFKColumn.ParentColumn != null)
            {
                var foundColumn = FindToColumnInParentTable(fromFKColumn, toFKColumn);
                toFKColumn.ParentColumn = foundColumn ?? CreateParentColumn(toFKColumn.ForeignKey, fromFKColumn);
            }
            if (fromFKColumn.RelatedColumn != null)
            {
                var foundColumn = FindToColumnInRelatedTable(fromFKColumn, toFKColumn);
                toFKColumn.RelatedColumn = foundColumn ?? CreateRelatedColumn(toFKColumn.ForeignKey, fromFKColumn);
            }
        }
         
        private DBColumn CreateRelatedColumn(DBForeignKey toFK, DBForeignKeyColumn fromFKColumn)
        {
            if (toFK == null || toFK.RelatedTable == null) return null;
            var columnMerger = MergeableBORegistry.Instance.Resolve<DBColumn>();
            var relatedColumn = columnMerger.MergeBOFrom(fromFKColumn.RelatedColumn, null);
            toFK.RelatedTable.Columns.Add(relatedColumn);
/*            var relatedColumn = toFK.RelatedTable.Columns.CreateBusinessObject();
            relatedColumn.ColumnName = fromFKColumn;
            relatedColumn.PendingChangeType = ChangeType.Add;*/
            return relatedColumn;
        }
        private DBColumn CreateParentColumn(DBForeignKey toFK, DBForeignKeyColumn fromFKColumn)
        {
            if (toFK == null || toFK.ParentTable == null) return null;
            var columnMerger = MergeableBORegistry.Instance.Resolve<DBColumn>();
            var parentColumn = columnMerger.MergeBOFrom(fromFKColumn.ParentColumn, null);
            toFK.ParentTable.Columns.Add(parentColumn);
/*            var parentColumn = toFK.ParentTable.Columns.CreateBusinessObject();
            parentColumn.ColumnName = parentColumnName;
            parentColumn.PendingChangeType = ChangeType.Add;*/
            return parentColumn;
        }

        private DBColumn FindToColumnInParentTable(DBForeignKeyColumn fromBO, DBForeignKeyColumn toBO)
        {
            if (toBO.ForeignKey == null || toBO.ForeignKey.ParentTable == null) return null;
            return toBO.ForeignKey.ParentTable.Columns.Find(column => column.ColumnName == fromBO.ParentColumnName);
        }
        private DBColumn FindToColumnInRelatedTable(DBForeignKeyColumn fromBO, DBForeignKeyColumn toBO)
        {
            if (toBO.ForeignKey == null || toBO.ForeignKey.RelatedTable == null) return null;
            return toBO.ForeignKey.RelatedTable.Columns.Find(column => column.ColumnName == fromBO.RelatedColumnName);
        }

        public override Func<DBForeignKeyColumn, bool> MatchBusinessObject(DBForeignKeyColumn boToFind)
        {
            return foundBO => boToFind != null && foundBO != null 
                              && foundBO.ParentColumnName == boToFind.ParentColumnName
                              && foundBO.RelatedColumnName == boToFind.RelatedColumnName;
        }
    }
}